package application;

import java.io.IOException;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Scanner;
/**
 * 
 */
import java.util.StringTokenizer;

import framework.File;
import framework.Folder;
import framework.FolderItem;



public class FileSystem {
    /**
     * the folder 
     */
	private  static Folder folder;
	private static PrintWriter FileErr = new PrintWriter(System.err, true);
    /**
     *  The function input 
     */
	private static Scanner FileIn = new Scanner(System.in);

	/**
	 * The main function try to use <code>File<code>, <code>Folder<code> 
	 * and <code>FolderItem<code> and comparing with using class java.io.File
	 * 
	 */
	public static void main(String[] args) throws IOException {
		/** Get the current user path and printout it */
		String path = System.getProperty("user.dir");
		
		/** Get specified path and printout it */
//		String path = "D:\\testFileSystem";
		
		System.out.println(path);

		/** Get the folder name */
		StringTokenizer tokenizer = new StringTokenizer(path, "\\");
		String folderName = tokenizer.nextToken();
		for (; tokenizer.hasMoreTokens();) {
			folderName = tokenizer.nextToken();
		}

		/** Get all file items <code>files<code> of the current user path */
		java.io.File file = new java.io.File(System.getProperty("user.dir"));
		
		/** Get all file items <code>files<code> of specified path */
//		java.io.File file = new java.io.File("D:\\testFileSystem");
		
		java.io.File[] files = file.listFiles();

		if (files != null) {

			/**
			 * Recursive printout all folder items of the current folder by
			 * using java.io.File
			 * 
			 */
			System.out.println(folderName);
			printFolderItems(file, "--");

			System.out.println("====Up:java.io.File========Down:filesystem===========");

			/**
			 * Recursive construct <code>folder<code> include all folder items
			 * by using <code>File<code>, <code>Folder<code>, <code>FolderItem<code>
			 * and java.io.File
			 * 
			 */
			 folder = new Folder(folderName);
			for (java.io.File f : files) {
				FolderItem folderItem;
				if (f.isFile()) {
					folderItem = new File(f.getName(), "  ", (int) f.length());
					folder.addFolderItem(folderItem);
				}
				if (f.isDirectory()) {
					folderItem = new Folder(f.getName());
					folder.addFolderItem(folderItem);
					constructFolderItems(f, (Folder) folderItem);
				}
			}
            
			FileSystem fileSystem = new FileSystem();
			fileSystem.run();
			
		}
	}
     
	private void run() throws IOException {

		

		int choice = getChoice();

		while (choice != 0) {

			if (choice == 1) {
				
			} else if (choice == 2){
				
			} else if (choice == 3){
				printAllFolder(folder);
			}else if (choice == 4){
				getNumberofFolder(folder,"--");
			}else if (choice == 5){
				getNumberofSpecificFolder(folder,"--");
			}else if (choice == 6){
				seekFolder(folder,readRoute(),0);
				seekRoute.clear();
			}


			choice = getChoice();
		}
	}
   /**
    * Obtains the choice to decide how to deal with the fileSystem
    * @return the choice 
    * @throws IOException
    */
	private int getChoice() throws IOException {

		do {

			int input;

			try {
				System.out.println();
				System.out.print(      "[0]  Quit\n" 
						   + "[1]  Add One FolderItem\n"
						   + "[2]  Remove One FolderItem\n"
						   + "[3]  Display All FolderItems\n"
						   + "[4]  Display All the number of FoulderItem\n" 
						   + "[5]  Display the number of specifit FoulderItem \n"
						   + "[6]  Judge the specifit folferitem is existing \n"
						   + "choice>");
				System.out.flush();

				input = Integer.parseInt(FileIn.nextLine());

				if (0 <= input && 6 >= input) {

					return input;

				} else {
					System.out.println("Invalid choice:  " + input);
				}
			} catch (NumberFormatException nfe) {
				FileErr.println(nfe);
			}
		} while (true);
	}
	/**
	 * Obtains a new name of  new folderItem from the user
	 * @return the name of the new folderItem
	 */
	public String getreadFolderItemName() {
		String theName =new String();

			System.out.println("Please input the new FolderItem name:");
			theName = FileIn.nextLine();

				
		return theName;
	}
	/**
	 * Recursive printout all folder items of the current folder by
	 * using <code>File<code>, <code>Folder<code> and <code>FolderItem<code>
	 * 
	 */
    public void printAllFolder(Folder f) {
    	
    	System.out.println(f.getName());
    	printFolderItems(f, "--");
    }
    /**
     * Obtain the route to found the Folder
     * the ArrayList<String> is a collection of String object.
     * @return the Route which help find the folderItem
     */
    public ArrayList<String> readRoute()  {
    	final String DELIM = "/";
    	ArrayList<String> Route= new ArrayList<String>();
		do {
			System.out.print(" the Route [bin/application](The folder Name):"); 
			
			StringTokenizer str = new StringTokenizer(FileIn.nextLine(), DELIM);
			
			 for(int i=0;str.hasMoreTokens();i++) {
					Route.add(str.nextToken());
					System.out.println(Route.get(i));
				}
			if (Route.get(0)=="filesystem") {
				FileErr.println("Invalid input:filesystem");
			} else {			
					break;
			  }
		} while (true);
       return Route;
    }
    /**
     * Obtains the all the number of all folder in fileSystem
     * @param the folder 
     * @param indent 
     */
	public void getNumberofFolder(Folder f,String indent){
		System.out.println(f.getName());
		System.out.println(indent+"have folderItems: "+f.getNumberOfFolderItems());
		for (FolderItem item : f.getFolderItems()) {
			if (item instanceof Folder) {
				getNumberofFolder((Folder) item, indent);
			}
		}
	}
	/**
     * Obtains the all the number of all folder in fileSystem
     * @param the Specific folder 
     * @param indent 
     */
	public void getNumberofSpecificFolder(Folder f,String indent){
		
		boolean isExist= seekFolder(f,readRoute(),0);
		System.out.println(seekRoute.size());
		if(isExist == false) {
			System.out.println("there don't have the folder,you can get the number of the folderitems.");;
		}
		else  if(isExist == true)
		{
			for(int i=0;i<seekRoute.size();i++) {
				if(f.getFolderItem(seekRoute.get(i)) instanceof Folder) {
					f = (Folder)f.getFolderItem(seekRoute.get(i));
					System.out.println(f.getName());
				}
			}			
		}
		System.out.println(indent+"have folderItems: "+f.getNumberOfFolderItems());
		seekRoute.clear();
		
	}
    /**
     * Judge the FolderItem is existing.
     */
	private static boolean isSeek = false;
    /**
      *  store the information about the route of the FolderItem
      */
	private static ArrayList<Integer> seekRoute = new ArrayList<Integer>();
	/**
	 * 
	 * @param the folder of fileSystem
	 * @param the folder route array
	 * @param the count is the index of the Route(ArrayList<String>)
	 * @return isSeek to judge whether the FolderItem is existing.
	 */
	public boolean seekFolder(Folder f,ArrayList<String> s,int count) {
		String[] seekf = new String[f.getNumberOfFolderItems()]; 
		int getindexof = 0;
		isSeek = false;
		for(int i=0;i<f.getNumberOfFolderItems();i++) {
			seekf[i]=f.getFolderItem(i).getName();
			//System.out.println(f.getFolderItem(i).getName());
			if(seekf[i].equals(s.get(count))==true) {
				isSeek = true;
				getindexof = i;
				seekRoute.add(i);
			}
		}
		if(isSeek==false) {
			System.out.println("Not found this folderItem:"+s.get(count));
		}
		else if(isSeek == true&&f.getFolderItem(getindexof) instanceof Folder) {
				if(s.size()-1==count) {
				System.out.println("The seeking is over.");
				System.out.println("found this folderItem:"+f.getFolderItem(getindexof).getName());
			}
				else if(s.size()-1>count){
				seekFolder((Folder)f.getFolderItem(getindexof), s,++count);
			}
        }
		else if(isSeek ==true&&f.getFolderItem(getindexof) instanceof File) {
			if(s.size()-1==count) {
				System.out.println("The seeking is over.");
				System.out.println("The FolderItem is a file.");
			}		
		}
		return isSeek;
	}
	
	/**
	 * Recursive construct <code>folder<coder> object of one folder 
	 * by using <code>File<code>, <code>Folder<code> and <code>FolderItem<code>
	 * and class java.io.File
	 * 
	 * @param f  a java.io.File's object
	 * @param folder  Folder
	 * 
	 */
	public static void constructFolderItems(java.io.File f, Folder folder) {
		java.io.File[] subFiles = f.listFiles();
		for (java.io.File i : subFiles) {
			FolderItem folderItem;
			if (i.isFile()) {
				folderItem = new File(i.getName(), "  ", (int) i.length());
				folder.addFolderItem(folderItem);
			}
			if (i.isDirectory()) {
				folderItem = new Folder(i.getName());
				folder.addFolderItem(folderItem);
				constructFolderItems(i, (Folder) folderItem);
			}
		}
	}

	/**
	 * Recursive printout all folder items under one folder
	 * only by using class java.io.File
	 * 
	 * @param f  a java.io.File's object
	 * @param indent  a String object for printing indentation
	 * 
	 */
	public static void printFolderItems(java.io.File f, String indent) {
		for (java.io.File i : f.listFiles()) {
			System.out.println(indent + i.getName());
			if (i.isDirectory()) {
				String indentTemp = indent + "--";
				printFolderItems(i, indentTemp);
			}
		}
	}

	/**
	 * Recursive printout all folder items under one folder by using
	 * <code>File<code>, <code>Folder<code> and <code>FolderItem<code>
	 * 
	 * @param f  a Folder object
	 * @param indent  a String object for printing indentation
	 * 
	 */
	public static void printFolderItems(Folder f, String indent) {
		for (FolderItem item : f.getFolderItems()) {
			System.out.println(indent + item.getName());
			if (item instanceof Folder) {
				String indentTemp = indent + "--";
				printFolderItems((Folder) item, indentTemp);
			}
		}
	}

}